<?php
/**
 * Created by lzl
 * Date: 2021 2021/10/15
 * Time: 10:43
 */

namespace App\Services\Api;

use App\Events\ConfirmReceiptEvent;
use App\Exceptions\RequestException;
use App\Forms\AddressForms;
use App\Forms\CartForms;
use App\Forms\ConfigForms;
use App\Forms\ExpressForms;
use App\Forms\GoodsAttributeForms;
use App\Forms\OrderForms;
use App\Forms\StockForms;
use App\Forms\UserForms;
use App\Models\Order;
use App\Models\OrderDetail;
use App\Services\BaseServices as Base;

class OrderServices extends Base
{

    /**
     * 购物车下单
     * @param $validated
     * @return array
     */
    public function cartPreview($validated)
    {

        $user = (new UserForms())->getUserDetail(UID);

        $attribute_form = new GoodsAttributeForms();

        $goods = [];

        //身份定价
        foreach ($validated['cart_ids'] as $k => $item) {

            $goods[$k] = (new CartForms())->cartDetail($item, ['id as cart_id', 'count', 'attribute_id'])->toArray();

            $attribute = $attribute_form->getGoodsAttributeDetail($goods[$k]['attribute_id']);

            $goods[$k]['detail'] = $attribute_form->getGoodsPreview($attribute, $user);

        }

        return array_merge(compact('goods'), $this->preview());
    }


    /**
     * 直接下单
     * @param $validated
     * @return array
     * @throws RequestException
     */
    public function submitPreview($validated)
    {
        $attribute_form = new GoodsAttributeForms();

        $attribute = $attribute_form->getGoodsAttributeDetail($validated['attribute_id']);

        //库存判断
        (new StockForms())->compareStock($attribute, $validated['count']);

        $goods[0] = $validated;

        //身份定价
        $goods[0]['detail'] = $attribute_form->getGoodsPreview($attribute, (new UserForms())->getUserDetail(UID));

        return array_merge(compact('goods'), $this->preview());
    }


    /**
     * @return array
     */
    public function preview()
    {
        //快递信息
        $express = [
            'express_min'    => (new ConfigForms())->getDetail('express_min')->value,
            'express_amount' => (new ConfigForms())->getDetail('express_amount')->value,
        ];

        //收货地址
        $address = (new AddressForms())->addressDefault(UID);

        return compact('express', 'address');
    }


    /**
     * 下单提交
     * @param $validated
     * @return Order|\Illuminate\Database\Eloquent\Model
     * @throws RequestException
     * @throws \Throwable
     */
    public function submit($validated)
    {
        \DB::beginTransaction();

        try{

            //处理价格开始
            $total_amount = $total_market_price = 0;

            foreach ($validated['goods'] as &$item){

                $attribute_form = new GoodsAttributeForms();

                $attribute = $attribute_form->getGoodsAttributeDetail($item['attribute_id']);

                //单品价格
                $price = $attribute_form->getGoodsPreview($attribute, (new UserForms())->getUserDetail(UID));

                $item['details'] = $price;
                $item['goods_id'] = $attribute->goods_id;

                if($validated['source']){ //插件订单
                    $total_amount = (new PluginServices())
                        ->orderPlugin($validated['source'])
                        ->getOrder($validated['source_id'])
                        ->amount;
                }else{
                    $total_amount = bcadd($total_amount, bcmul($price['pay_price'], $item['count'],2),2) ;
                }

                $total_market_price = bcadd($total_market_price, bcmul($price['market_price'] , $item['count'],2),2);

            }


            $validated['total_market_price'] = $total_market_price;
            $validated['transfer_amount'] = 0;


            $express = $this->preview();

            if($total_amount <  $express['express']['express_min']){
                $total_amount = bcadd($total_amount, $express['express']['express_amount'],2);
                $validated['transfer_amount'] = $express['express']['express_amount'];
            }
            //处理价格结束

            //对比价格
            if($total_amount != $validated['pay_amount']){
                throw new RequestException('下单异常，请稍后重试');
            }

            $user = (new UserForms())->getUserDetail(UID);

            //生成订单 =》 [ 处理库存 处理购物车 ]
            $order = $this->generateOrder($validated);

            \DB::commit();

            //支付
            $payment = new PaymentService();
            $payment->order = $order;
            $payment->user = $user;

            return array_merge($order->toArray(), $payment->orderPayment());

        }catch (\Exception $e){
            \DB::rollBack();

            throw new RequestException($e->getMessage());
        }

    }

    /**
     * @param $validated
     * @return Order|\Illuminate\Database\Eloquent\Model
     * @throws RequestException
     */
    protected function generateOrder($validated)
    {

        $address = (new AddressForms())->addressDetail($validated['address_id']);

        $forms = new OrderForms();

        $order = $forms->createOrder([
            'order_sn'        => $this->getOrderNo('DXT'),
            'uid'             => UID,
            'amount'          => $validated['total_market_price'],
            'pay_amount'      => $validated['pay_amount'],
            'address'         => $address->province . $address->city . $address->area . $address->details,
            'name'            => $address->name,
            'phone'           => $address->phone,
            'transfer_amount' => $validated['transfer_amount'],
            'message'         => $validated['message'],
            'source'          => $validated['source'],
            'source_id'       => $validated['source_id'],
        ]);

        if($validated['source']){ //插件订单
            (new PluginServices())->orderPlugin($validated['source'])->submitOrder($validated['source_id']);
        }

        foreach ($validated['goods'] as $k => $item){


            $attribute_value = '';

            if($item['details']['sku']){
                foreach ($item['details']['sku'] as $attKey =>  $attItem){
                    $attribute_value .= ($attKey == 0 ? '': ' ' ).$attItem[0];
                }
            }

            $forms->createOrderDetail([
                'order_id'        => $order->id,
                'attribute_id'    => $item['attribute_id'],
                'attribute_value' => $attribute_value,
                'good_id'         => $item['goods_id'],
                'good_name'       => $item['details']['goods_name'],
                'goods_count'     => $item['count'],
                'goods_image'     => $item['details']['images'],
                'goods_price'     => $item['details']['market_price'],
                'goods_pay_price' => $item['details']['pay_price'],
            ]);

            //处理购物车
            if(isset($item['cart_id']) && filled($item['cart_id'])){
                (new CartForms())->deleteCartById($item['cart_id']);
            }else{
                //直接下单的处理库存，购物车中商品已经处理过库存了
                (new StockForms())->editStock($item['attribute_id'], -$item['count']);
            }

        }

        return $order;

    }


    /**
     * 确认支付
     * @param $validated
     * @return array
     * @throws RequestException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function confirmPay($validated)
    {
        $order = (new OrderForms())->getOrderDetail($validated['id']);

        if($order->status != Order::UN_PAY || $order->uid != UID){
            throw new RequestException('支付订单异常！');
        }

        $payment = new PaymentService();
        $payment->order = $order;
        $payment->user = (new UserForms())->getUserDetail(UID);

        return array_merge($order->toArray(), $payment->orderPayment());
    }


    /**
     * 取消订单
     * @param $validated
     * @return bool
     * @throws RequestException
     */
    public function cancel($validated)
    {
        $order = (new OrderForms())->getOrderDetail($validated['id']);

        if($order->status != Order::UN_PAY || $order->uid != UID){
            throw new RequestException('订单异常！');
        }

        //取消订单 库存回增
        (new OrderForms())->updateOrder($order->id, ['status' => Order::CANCEL]);

        foreach ($order->details as $item){

            /**
             * @var $item OrderDetail
             */
            (new StockForms())->editStock($item->attribute_id, $item->goods_count);
        }

        return true;
    }


    /**
     * 异步通知
     * @throws \EasyWeChat\Kernel\Exceptions\Exception
     */
    public function notify()
    {
        return (new PaymentService())->notify(new Order());
    }

    /**
     * 生成不重复订单号
     * @return string
     */
    public function getOrderNo($per)
    {

        $n = get_order_no($per);
        while (true){
            if(!Order::where('order_sn' ,$n)->exists()){
                break;
            }
            $n = get_order_no($per);
        }

        return $n;
    }


    /**
     * 订单列表
     * @param $validated
     * @return mixed
     */
    public function getOrderList($validated)
    {
        $validated['uid'] = UID;

        return (new OrderForms())->getOrderList($validated);
    }


    /**
     * 确认收货
     * @param $validated
     * @return bool|int
     * @throws RequestException
     */
    public function confirmCollect($validated)
    {
        $orderForms = new OrderForms();

        $order = $orderForms->getOrderDetail($validated['id']);

        if($order->uid == UID && $order->status == Order::RECEIVING){

            event(new ConfirmReceiptEvent($order));

            return $orderForms->updateOrder($validated['id'], [
                'status' => Order::SUCCESS,
                'receive_time' => date('Y-m-d H:i:s')
            ]);
        }

        throw new RequestException('订单数据异常，收货失败');
    }


    /**
     * 订单详情
     * @param $id
     * @return array
     */
    public function orderDetail($id)
    {
        $orderForms = new OrderForms();

        $order = $orderForms->getOrderDetail($id)->toArray();
        $order['detail'] = $orderForms->orderDetailList($id);
//        $order['express'] = (new ExpressForms())->getOrderExpress($id);

        return $order;
    }


    /**
     * 物流详情
     * @param $id
     * @return \App\Models\OrderExpress|array|\Illuminate\Database\Eloquent\Model|null|object
     * @throws RequestException
     */
    public function orderExpress($id)
    {
        $orderForms = new OrderForms();
        $order = $orderForms->getOrderDetail($id);

        if($order->status >= Order::RECEIVING){

            $express = new ExpressForms();

            $express->updateOrderExpress($id);

            $data = $express->getOrderExpress($id)->toArray();

            $data['express_details'] = array_reverse(json_decode($data['express_details'], true) ?: []);

            return  $data;
        }

        return [];
    }



}
